﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace XnaTools
{
    public class TrackballCamera
    {

        public float FarPlane { get; set; }

        private Quaternion _quat;

        private Vector3 _originalPosition = new Vector3(0, 0, 10.0f);

        public Vector3 OriginalPosition
        {
            get { return _originalPosition; }
            set
            {
                _originalPosition = value;
                _view = Matrix.CreateLookAt(value, Vector3.Zero, Up);
                _position = value;
            }
        }

        private Vector3 _position;

        public Vector3 Position
        {
            get { return _position; }
        }


        private Vector3 _up = Vector3.Up;

        public Vector3 Up
        {
            get { return _up; }
            set { _up = value; }
        }



        private Matrix _view;

        public Matrix View
        {
            get { return _view; }
        }

        private Matrix _proj;

        public Matrix Proj
        {
            get { return _proj; }
        }


        public  TrackballCamera()
        {
            _view = Matrix.CreateLookAt(_originalPosition, new Vector3(0,0,0), _up);
            _quat = Quaternion.Identity;
            FarPlane = 1000;
            _position = OriginalPosition;
        }

        private bool _isMouseDown;
        private float _lastMouseX, _lastMouseY;

        public void Update(MouseState mouse, float screenWidth, float screenHeight)
        {

            if (mouse.LeftButton)
            {
                if (!_isMouseDown)
                {
                    _isMouseDown = true;
                    _lastMouseX = mouse.X;
                    _lastMouseY = mouse.Y;
                }
                else
                {
                    float deltaX = mouse.X - _lastMouseX;
                    float deltaY = mouse.Y - _lastMouseY;

                    var radianX = -(deltaX / screenWidth) * MathHelper.TwoPi;
                    var radianY = -(deltaY / screenHeight) * MathHelper.TwoPi;

                    var rotation = Quaternion.CreateFromYawPitchRoll(radianX, radianY, 0);
                    _quat = _quat * rotation;
                    _quat.Normalize();
                    var position = Vector3.Transform(_originalPosition, _quat);
                    var up = Vector3.Transform(_up, _quat);

                    _view = Matrix.CreateLookAt(position, Vector3.Zero, up);

                    _position = position;


                    _lastMouseX = mouse.X;
                    _lastMouseY = mouse.Y;
                }
            }
            else
            {
                _isMouseDown = false;
            }

            _proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, screenWidth / screenHeight,
                                                        0.1f, FarPlane);
        }
    }
}
